module CRC16_128B_RX (
			rst,   	
			clk,   			
   			dval, 
   			sop,
   			eop,
   			eop_dmod,	 
   			data,  
   			
   			crc16_rdy,
   			crc16_ok
			);
			
input			rst;
input			clk;
input			dval;
input           sop; 			    
input           eop;
input	[4:0]	eop_dmod;
input  	[127:0]	data;

output          crc16_rdy;
output			crc16_ok;
reg             crc16_rdy;
reg 			crc16_ok;
	

////////////////////////////////////////
//////int reg//////////////////////////
///////////////////////////////////////
reg		[4:0]	eop_dmod_d1; 
reg		[4:0]	eop_dmod_d2; 
reg		[4:0]	eop_dmod_d3; 
reg				dval_d1;       
reg		[127:0]	data_valid;
reg             sop_d1;
reg				eop_d1;
reg				eop_d2;
reg				eop_d3;
reg				eop_d4;
////////////////////////////
reg     [15:0]  crc16_d128;

reg     [15:0]  crc16_b1;

/////////////////////////////////////////////////////////
always @(posedge rst or posedge clk)
begin 
	if (rst == 1'b1)
	begin  
	    dval_d1     <= 1'b0;
	    sop_d1      <= 1'b0;
	    eop_d1      <= 1'b0; 
	    eop_d2      <= 1'b0; 
	    eop_d3      <= 1'b0; 
	    eop_d4      <= 1'b0;
	    eop_dmod_d1 <= 5'h00;
	    eop_dmod_d2 <= 5'h00;
	    eop_dmod_d3 <= 5'h00;
	end
	else
	begin
	    dval_d1     <= dval;
	    sop_d1      <= sop;
	    eop_d1      <= eop; 
	    eop_d2      <= eop_d1; 
	    eop_d3      <= eop_d2; 
	    eop_d4      <= eop_d3;
	    eop_dmod_d1 <= eop_dmod;
	    eop_dmod_d2 <= eop_dmod_d1;
	    eop_dmod_d3 <= eop_dmod_d2;
	end
end	

always @(posedge rst or posedge clk)
begin 
	if (rst == 1'b1)
		data_valid <= 128'd0;
	else if (eop)	
	    case (eop_dmod)	        
	        5'h01 : data_valid <= {data[127:120],120'd0};
	        5'h02 : data_valid <= {data[127:112],112'd0};
	        5'h03 : data_valid <= {data[127:104],104'd0};
	        5'h04 : data_valid <= {data[127:96],96'd0};
	        5'h05 : data_valid <= {data[127:88],88'd0};
	        5'h06 : data_valid <= {data[127:80],80'd0};
	        5'h07 : data_valid <= {data[127:72],72'd0};
	        5'h08 : data_valid <= {data[127:64],64'd0};
	        5'h09 : data_valid <= {data[127:56],56'd0};
	        5'h0A : data_valid <= {data[127:48],48'd0};
	        5'h0B : data_valid <= {data[127:40],40'd0};
	        5'h0C : data_valid <= {data[127:32],32'd0};
	        5'h0D : data_valid <= {data[127:24],24'd0};
	        5'h0E : data_valid <= {data[127:16],16'd0};
	        5'h0F : data_valid <= {data[127:8],8'd0};    
	        5'h10 : data_valid <= data;   
	      default : data_valid <= 128'd0;   
	    endcase    
    else
        data_valid <= data;	       
end	

always @(posedge rst or posedge clk)
begin 
	if (rst == 1'b1)	
	    crc16_d128 <= 16'hFFFF;
    else if (dval_d1)
        if (sop_d1)
            crc16_d128 <= CRC16_D128(data_valid,16'hFFFF);
        else
            crc16_d128 <= CRC16_D128(data_valid,crc16_d128);    
end    

always @(posedge rst or posedge clk)
begin 
	if (rst == 1'b1)
        crc16_b1 <= 16'hFFFF;
    else if(eop_d2) 
        crc16_b1 <= crc16_d128;   	     
end	

always @(posedge rst or posedge clk)
begin 
	if (rst == 1'b1)
        crc16_ok <= 1'b0;
    else if(eop_d3) 
        case (eop_dmod_d3)
            5'h01 : crc16_ok <= (crc16_b1 == 16'hC7EC);
            5'h02 : crc16_ok <= (crc16_b1 == 16'h6A0A);
            5'h03 : crc16_ok <= (crc16_b1 == 16'h4EC3);            
            5'h04 : crc16_ok <= (crc16_b1 == 16'hA96A);
            5'h05 : crc16_ok <= (crc16_b1 == 16'h280C);
            5'h06 : crc16_ok <= (crc16_b1 == 16'h84F9);
            5'h07 : crc16_ok <= (crc16_b1 == 16'hD40F);
            5'h08 : crc16_ok <= (crc16_b1 == 16'hE139);
            5'h09 : crc16_ok <= (crc16_b1 == 16'h1872);
            5'h0A : crc16_ok <= (crc16_b1 == 16'h313E);
            5'h0B : crc16_ok <= (crc16_b1 == 16'hF1CE);
            5'h0C : crc16_ok <= (crc16_b1 == 16'h0E10);
            5'h0D : crc16_ok <= (crc16_b1 == 16'h110C);
            5'h0E : crc16_ok <= (crc16_b1 == 16'h84C0);
            5'h0F : crc16_ok <= (crc16_b1 == 16'hCC9C);
            5'h10 : crc16_ok <= (crc16_b1 == 16'h1D0F);
          default : crc16_ok <= 1'b0;    
        endcase 
end

always @(posedge rst or posedge clk)
begin 
	if (rst == 1'b1)
        crc16_rdy  <= 1'b0;    
    else
        crc16_rdy <= eop_d3;  
end   

/////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////                      CRC Function                     ///////////////////////////////////      	                   	       			              
function [15:0] CRC16_D128;

  input [127:0] Data;
  input [15:0] crc;
  reg [127:0] d;
  reg [15:0] c;
  reg [15:0] newcrc;
begin
  d = Data;
  c = crc;

  newcrc[0] = d[127] ^ d[123] ^ d[121] ^ d[118] ^ d[115] ^ d[113] ^ d[110] ^ d[109] ^ d[108] ^ d[107] ^ d[106] ^ d[104] ^ d[98] ^ d[96] ^ d[95] ^ d[88] ^ d[86] ^ d[84] ^ d[82] ^ d[81] ^ d[80] ^ d[77] ^ d[75] ^ d[74] ^ d[72] ^ d[70] ^ d[67] ^ d[66] ^ d[65] ^ d[64] ^ d[63] ^ d[58] ^ d[56] ^ d[55] ^ d[52] ^ d[51] ^ d[49] ^ d[48] ^ d[42] ^ d[35] ^ d[33] ^ d[32] ^ d[28] ^ d[27] ^ d[26] ^ d[22] ^ d[20] ^ d[19] ^ d[12] ^ d[11] ^ d[8] ^ d[4] ^ d[0] ^ c[1] ^ c[3] ^ c[6] ^ c[9] ^ c[11] ^ c[15];
  newcrc[1] = d[124] ^ d[122] ^ d[119] ^ d[116] ^ d[114] ^ d[111] ^ d[110] ^ d[109] ^ d[108] ^ d[107] ^ d[105] ^ d[99] ^ d[97] ^ d[96] ^ d[89] ^ d[87] ^ d[85] ^ d[83] ^ d[82] ^ d[81] ^ d[78] ^ d[76] ^ d[75] ^ d[73] ^ d[71] ^ d[68] ^ d[67] ^ d[66] ^ d[65] ^ d[64] ^ d[59] ^ d[57] ^ d[56] ^ d[53] ^ d[52] ^ d[50] ^ d[49] ^ d[43] ^ d[36] ^ d[34] ^ d[33] ^ d[29] ^ d[28] ^ d[27] ^ d[23] ^ d[21] ^ d[20] ^ d[13] ^ d[12] ^ d[9] ^ d[5] ^ d[1] ^ c[2] ^ c[4] ^ c[7] ^ c[10] ^ c[12];
  newcrc[2] = d[125] ^ d[123] ^ d[120] ^ d[117] ^ d[115] ^ d[112] ^ d[111] ^ d[110] ^ d[109] ^ d[108] ^ d[106] ^ d[100] ^ d[98] ^ d[97] ^ d[90] ^ d[88] ^ d[86] ^ d[84] ^ d[83] ^ d[82] ^ d[79] ^ d[77] ^ d[76] ^ d[74] ^ d[72] ^ d[69] ^ d[68] ^ d[67] ^ d[66] ^ d[65] ^ d[60] ^ d[58] ^ d[57] ^ d[54] ^ d[53] ^ d[51] ^ d[50] ^ d[44] ^ d[37] ^ d[35] ^ d[34] ^ d[30] ^ d[29] ^ d[28] ^ d[24] ^ d[22] ^ d[21] ^ d[14] ^ d[13] ^ d[10] ^ d[6] ^ d[2] ^ c[0] ^ c[3] ^ c[5] ^ c[8] ^ c[11] ^ c[13];
  newcrc[3] = d[126] ^ d[124] ^ d[121] ^ d[118] ^ d[116] ^ d[113] ^ d[112] ^ d[111] ^ d[110] ^ d[109] ^ d[107] ^ d[101] ^ d[99] ^ d[98] ^ d[91] ^ d[89] ^ d[87] ^ d[85] ^ d[84] ^ d[83] ^ d[80] ^ d[78] ^ d[77] ^ d[75] ^ d[73] ^ d[70] ^ d[69] ^ d[68] ^ d[67] ^ d[66] ^ d[61] ^ d[59] ^ d[58] ^ d[55] ^ d[54] ^ d[52] ^ d[51] ^ d[45] ^ d[38] ^ d[36] ^ d[35] ^ d[31] ^ d[30] ^ d[29] ^ d[25] ^ d[23] ^ d[22] ^ d[15] ^ d[14] ^ d[11] ^ d[7] ^ d[3] ^ c[0] ^ c[1] ^ c[4] ^ c[6] ^ c[9] ^ c[12] ^ c[14];
  newcrc[4] = d[127] ^ d[125] ^ d[122] ^ d[119] ^ d[117] ^ d[114] ^ d[113] ^ d[112] ^ d[111] ^ d[110] ^ d[108] ^ d[102] ^ d[100] ^ d[99] ^ d[92] ^ d[90] ^ d[88] ^ d[86] ^ d[85] ^ d[84] ^ d[81] ^ d[79] ^ d[78] ^ d[76] ^ d[74] ^ d[71] ^ d[70] ^ d[69] ^ d[68] ^ d[67] ^ d[62] ^ d[60] ^ d[59] ^ d[56] ^ d[55] ^ d[53] ^ d[52] ^ d[46] ^ d[39] ^ d[37] ^ d[36] ^ d[32] ^ d[31] ^ d[30] ^ d[26] ^ d[24] ^ d[23] ^ d[16] ^ d[15] ^ d[12] ^ d[8] ^ d[4] ^ c[0] ^ c[1] ^ c[2] ^ c[5] ^ c[7] ^ c[10] ^ c[13] ^ c[15];
  newcrc[5] = d[127] ^ d[126] ^ d[121] ^ d[120] ^ d[114] ^ d[112] ^ d[111] ^ d[110] ^ d[108] ^ d[107] ^ d[106] ^ d[104] ^ d[103] ^ d[101] ^ d[100] ^ d[98] ^ d[96] ^ d[95] ^ d[93] ^ d[91] ^ d[89] ^ d[88] ^ d[87] ^ d[85] ^ d[84] ^ d[81] ^ d[79] ^ d[74] ^ d[71] ^ d[69] ^ d[68] ^ d[67] ^ d[66] ^ d[65] ^ d[64] ^ d[61] ^ d[60] ^ d[58] ^ d[57] ^ d[55] ^ d[54] ^ d[53] ^ d[52] ^ d[51] ^ d[49] ^ d[48] ^ d[47] ^ d[42] ^ d[40] ^ d[38] ^ d[37] ^ d[35] ^ d[31] ^ d[28] ^ d[26] ^ d[25] ^ d[24] ^ d[22] ^ d[20] ^ d[19] ^ d[17] ^ d[16] ^ d[13] ^ d[12] ^ d[11] ^ d[9] ^ d[8] ^ d[5] ^ d[4] ^ d[0] ^ c[0] ^ c[2] ^ c[8] ^ c[9] ^ c[14] ^ c[15];
  newcrc[6] = d[127] ^ d[122] ^ d[121] ^ d[115] ^ d[113] ^ d[112] ^ d[111] ^ d[109] ^ d[108] ^ d[107] ^ d[105] ^ d[104] ^ d[102] ^ d[101] ^ d[99] ^ d[97] ^ d[96] ^ d[94] ^ d[92] ^ d[90] ^ d[89] ^ d[88] ^ d[86] ^ d[85] ^ d[82] ^ d[80] ^ d[75] ^ d[72] ^ d[70] ^ d[69] ^ d[68] ^ d[67] ^ d[66] ^ d[65] ^ d[62] ^ d[61] ^ d[59] ^ d[58] ^ d[56] ^ d[55] ^ d[54] ^ d[53] ^ d[52] ^ d[50] ^ d[49] ^ d[48] ^ d[43] ^ d[41] ^ d[39] ^ d[38] ^ d[36] ^ d[32] ^ d[29] ^ d[27] ^ d[26] ^ d[25] ^ d[23] ^ d[21] ^ d[20] ^ d[18] ^ d[17] ^ d[14] ^ d[13] ^ d[12] ^ d[10] ^ d[9] ^ d[6] ^ d[5] ^ d[1] ^ c[0] ^ c[1] ^ c[3] ^ c[9] ^ c[10] ^ c[15];
  newcrc[7] = d[123] ^ d[122] ^ d[116] ^ d[114] ^ d[113] ^ d[112] ^ d[110] ^ d[109] ^ d[108] ^ d[106] ^ d[105] ^ d[103] ^ d[102] ^ d[100] ^ d[98] ^ d[97] ^ d[95] ^ d[93] ^ d[91] ^ d[90] ^ d[89] ^ d[87] ^ d[86] ^ d[83] ^ d[81] ^ d[76] ^ d[73] ^ d[71] ^ d[70] ^ d[69] ^ d[68] ^ d[67] ^ d[66] ^ d[63] ^ d[62] ^ d[60] ^ d[59] ^ d[57] ^ d[56] ^ d[55] ^ d[54] ^ d[53] ^ d[51] ^ d[50] ^ d[49] ^ d[44] ^ d[42] ^ d[40] ^ d[39] ^ d[37] ^ d[33] ^ d[30] ^ d[28] ^ d[27] ^ d[26] ^ d[24] ^ d[22] ^ d[21] ^ d[19] ^ d[18] ^ d[15] ^ d[14] ^ d[13] ^ d[11] ^ d[10] ^ d[7] ^ d[6] ^ d[2] ^ c[0] ^ c[1] ^ c[2] ^ c[4] ^ c[10] ^ c[11];
  newcrc[8] = d[124] ^ d[123] ^ d[117] ^ d[115] ^ d[114] ^ d[113] ^ d[111] ^ d[110] ^ d[109] ^ d[107] ^ d[106] ^ d[104] ^ d[103] ^ d[101] ^ d[99] ^ d[98] ^ d[96] ^ d[94] ^ d[92] ^ d[91] ^ d[90] ^ d[88] ^ d[87] ^ d[84] ^ d[82] ^ d[77] ^ d[74] ^ d[72] ^ d[71] ^ d[70] ^ d[69] ^ d[68] ^ d[67] ^ d[64] ^ d[63] ^ d[61] ^ d[60] ^ d[58] ^ d[57] ^ d[56] ^ d[55] ^ d[54] ^ d[52] ^ d[51] ^ d[50] ^ d[45] ^ d[43] ^ d[41] ^ d[40] ^ d[38] ^ d[34] ^ d[31] ^ d[29] ^ d[28] ^ d[27] ^ d[25] ^ d[23] ^ d[22] ^ d[20] ^ d[19] ^ d[16] ^ d[15] ^ d[14] ^ d[12] ^ d[11] ^ d[8] ^ d[7] ^ d[3] ^ c[1] ^ c[2] ^ c[3] ^ c[5] ^ c[11] ^ c[12];
  newcrc[9] = d[125] ^ d[124] ^ d[118] ^ d[116] ^ d[115] ^ d[114] ^ d[112] ^ d[111] ^ d[110] ^ d[108] ^ d[107] ^ d[105] ^ d[104] ^ d[102] ^ d[100] ^ d[99] ^ d[97] ^ d[95] ^ d[93] ^ d[92] ^ d[91] ^ d[89] ^ d[88] ^ d[85] ^ d[83] ^ d[78] ^ d[75] ^ d[73] ^ d[72] ^ d[71] ^ d[70] ^ d[69] ^ d[68] ^ d[65] ^ d[64] ^ d[62] ^ d[61] ^ d[59] ^ d[58] ^ d[57] ^ d[56] ^ d[55] ^ d[53] ^ d[52] ^ d[51] ^ d[46] ^ d[44] ^ d[42] ^ d[41] ^ d[39] ^ d[35] ^ d[32] ^ d[30] ^ d[29] ^ d[28] ^ d[26] ^ d[24] ^ d[23] ^ d[21] ^ d[20] ^ d[17] ^ d[16] ^ d[15] ^ d[13] ^ d[12] ^ d[9] ^ d[8] ^ d[4] ^ c[0] ^ c[2] ^ c[3] ^ c[4] ^ c[6] ^ c[12] ^ c[13];
  newcrc[10] = d[126] ^ d[125] ^ d[119] ^ d[117] ^ d[116] ^ d[115] ^ d[113] ^ d[112] ^ d[111] ^ d[109] ^ d[108] ^ d[106] ^ d[105] ^ d[103] ^ d[101] ^ d[100] ^ d[98] ^ d[96] ^ d[94] ^ d[93] ^ d[92] ^ d[90] ^ d[89] ^ d[86] ^ d[84] ^ d[79] ^ d[76] ^ d[74] ^ d[73] ^ d[72] ^ d[71] ^ d[70] ^ d[69] ^ d[66] ^ d[65] ^ d[63] ^ d[62] ^ d[60] ^ d[59] ^ d[58] ^ d[57] ^ d[56] ^ d[54] ^ d[53] ^ d[52] ^ d[47] ^ d[45] ^ d[43] ^ d[42] ^ d[40] ^ d[36] ^ d[33] ^ d[31] ^ d[30] ^ d[29] ^ d[27] ^ d[25] ^ d[24] ^ d[22] ^ d[21] ^ d[18] ^ d[17] ^ d[16] ^ d[14] ^ d[13] ^ d[10] ^ d[9] ^ d[5] ^ c[0] ^ c[1] ^ c[3] ^ c[4] ^ c[5] ^ c[7] ^ c[13] ^ c[14];
  newcrc[11] = d[127] ^ d[126] ^ d[120] ^ d[118] ^ d[117] ^ d[116] ^ d[114] ^ d[113] ^ d[112] ^ d[110] ^ d[109] ^ d[107] ^ d[106] ^ d[104] ^ d[102] ^ d[101] ^ d[99] ^ d[97] ^ d[95] ^ d[94] ^ d[93] ^ d[91] ^ d[90] ^ d[87] ^ d[85] ^ d[80] ^ d[77] ^ d[75] ^ d[74] ^ d[73] ^ d[72] ^ d[71] ^ d[70] ^ d[67] ^ d[66] ^ d[64] ^ d[63] ^ d[61] ^ d[60] ^ d[59] ^ d[58] ^ d[57] ^ d[55] ^ d[54] ^ d[53] ^ d[48] ^ d[46] ^ d[44] ^ d[43] ^ d[41] ^ d[37] ^ d[34] ^ d[32] ^ d[31] ^ d[30] ^ d[28] ^ d[26] ^ d[25] ^ d[23] ^ d[22] ^ d[19] ^ d[18] ^ d[17] ^ d[15] ^ d[14] ^ d[11] ^ d[10] ^ d[6] ^ c[0] ^ c[1] ^ c[2] ^ c[4] ^ c[5] ^ c[6] ^ c[8] ^ c[14] ^ c[15];
  newcrc[12] = d[123] ^ d[119] ^ d[117] ^ d[114] ^ d[111] ^ d[109] ^ d[106] ^ d[105] ^ d[104] ^ d[103] ^ d[102] ^ d[100] ^ d[94] ^ d[92] ^ d[91] ^ d[84] ^ d[82] ^ d[80] ^ d[78] ^ d[77] ^ d[76] ^ d[73] ^ d[71] ^ d[70] ^ d[68] ^ d[66] ^ d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[59] ^ d[54] ^ d[52] ^ d[51] ^ d[48] ^ d[47] ^ d[45] ^ d[44] ^ d[38] ^ d[31] ^ d[29] ^ d[28] ^ d[24] ^ d[23] ^ d[22] ^ d[18] ^ d[16] ^ d[15] ^ d[8] ^ d[7] ^ d[4] ^ d[0] ^ c[2] ^ c[5] ^ c[7] ^ c[11];
  newcrc[13] = d[124] ^ d[120] ^ d[118] ^ d[115] ^ d[112] ^ d[110] ^ d[107] ^ d[106] ^ d[105] ^ d[104] ^ d[103] ^ d[101] ^ d[95] ^ d[93] ^ d[92] ^ d[85] ^ d[83] ^ d[81] ^ d[79] ^ d[78] ^ d[77] ^ d[74] ^ d[72] ^ d[71] ^ d[69] ^ d[67] ^ d[64] ^ d[63] ^ d[62] ^ d[61] ^ d[60] ^ d[55] ^ d[53] ^ d[52] ^ d[49] ^ d[48] ^ d[46] ^ d[45] ^ d[39] ^ d[32] ^ d[30] ^ d[29] ^ d[25] ^ d[24] ^ d[23] ^ d[19] ^ d[17] ^ d[16] ^ d[9] ^ d[8] ^ d[5] ^ d[1] ^ c[0] ^ c[3] ^ c[6] ^ c[8] ^ c[12];
  newcrc[14] = d[125] ^ d[121] ^ d[119] ^ d[116] ^ d[113] ^ d[111] ^ d[108] ^ d[107] ^ d[106] ^ d[105] ^ d[104] ^ d[102] ^ d[96] ^ d[94] ^ d[93] ^ d[86] ^ d[84] ^ d[82] ^ d[80] ^ d[79] ^ d[78] ^ d[75] ^ d[73] ^ d[72] ^ d[70] ^ d[68] ^ d[65] ^ d[64] ^ d[63] ^ d[62] ^ d[61] ^ d[56] ^ d[54] ^ d[53] ^ d[50] ^ d[49] ^ d[47] ^ d[46] ^ d[40] ^ d[33] ^ d[31] ^ d[30] ^ d[26] ^ d[25] ^ d[24] ^ d[20] ^ d[18] ^ d[17] ^ d[10] ^ d[9] ^ d[6] ^ d[2] ^ c[1] ^ c[4] ^ c[7] ^ c[9] ^ c[13];
  newcrc[15] = d[126] ^ d[122] ^ d[120] ^ d[117] ^ d[114] ^ d[112] ^ d[109] ^ d[108] ^ d[107] ^ d[106] ^ d[105] ^ d[103] ^ d[97] ^ d[95] ^ d[94] ^ d[87] ^ d[85] ^ d[83] ^ d[81] ^ d[80] ^ d[79] ^ d[76] ^ d[74] ^ d[73] ^ d[71] ^ d[69] ^ d[66] ^ d[65] ^ d[64] ^ d[63] ^ d[62] ^ d[57] ^ d[55] ^ d[54] ^ d[51] ^ d[50] ^ d[48] ^ d[47] ^ d[41] ^ d[34] ^ d[32] ^ d[31] ^ d[27] ^ d[26] ^ d[25] ^ d[21] ^ d[19] ^ d[18] ^ d[11] ^ d[10] ^ d[7] ^ d[3] ^ c[0] ^ c[2] ^ c[5] ^ c[8] ^ c[10] ^ c[14];
  CRC16_D128 = newcrc;
end
endfunction



endmodule             